package com.nxy.cpfsfe.util;

import com.adtec.starring.exception.BaseException;
import com.adtec.starring.global.SysDef;
import com.adtec.starring.respool.SystemParameter;
import com.adtec.starring.util.SpringUtil;
import com.nxy.cpfsfe.PubBeanSerial;
import com.nxy.cpfsfe.enumtype.MsgCdOrTpEnum;
import com.nxy.cpfsfe.enumtype.RespCd;
import com.nxy.cpfsfe.enumtype.TcSequenceEnum;
import com.nxy.cpfsfe.mybatis.mapper.ToOrgMapper;
import com.nxy.cpfsfe.mybatis.pojo.ToOrg;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.SqlSession;
import org.dom4j.DocumentException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;


public class XmlCBSBuildUtil {
	private final static Logger LOGGER = LoggerFactory.getLogger(XmlCBSBuildUtil.class);

	/**
	 * 发送CBS报文
	 * @param bizMsg
	 * @param map
	 */
	public static  void responseSend(String bizMsg,Map map){

	}
	/**
	 * 组装cbs报文头
	 * @param xmlReqDoc xml报文模板文件
	 * @param code 报文编码
	 * @param map 数据存放map
	 */
	public  static void buildXmlRequestHead(XMLNodeUtil xmlReqDoc, String code, Map map) {
		String date = DateUtil.getDate();
		String time = DateUtil.getTime();
		xmlReqDoc.setNodeContentTrim("transaction/header/msg/msgCd", code);  //报文编号
		xmlReqDoc.setNodeContentTrim("transaction/header/msg/callTyp", "SYN");  //调用模式           说明：是否必填O 长度：4   备注：SYN同步，ASYN异步
		if(StringUtils.isBlank((String)map.get("seqNb"))){
			map.put("seqNb",PubBeanSerial.getInstance().getSeqNoAndIncrea(TcSequenceEnum.SEQ_NB.getCode()));
		}
		String seqNb = (String)map.get("seqNb");
		xmlReqDoc.setNodeContentTrim("transaction/header/msg/seqNb", StringUtil.trimObject(seqNb));  //报文流水号         说明：是否必填M 长度：15  备注 000000000000001
//		xmlReqDoc.setNodeContentTrim("transaction/header/msg/sndMbrCd", StringUtil.trimObject(map.get("/root/MsgHeader/SndBankId")));  //报文发起成员编号
		xmlReqDoc.setNodeContentTrim("transaction/header/msg/sndMbrCd", "0000");  //报文发起成员编号
		xmlReqDoc.setNodeContentTrim("transaction/header/msg/sndAppCd", "NNS");  //报文发起应用编号
//		xmlReqDoc.setNodeContentTrim("transaction/header/msg/sndAppCd", StringUtil.trimObject(map.get("/root/MsgHeader/SndSysId")));  //报文发起应用编号
		xmlReqDoc.setNodeContentTrim("transaction/header/msg/sndDt", date);  //报文发起日期       说明：是否必填M 长度：8
		xmlReqDoc.setNodeContentTrim("transaction/header/msg/sndTm",time);  //报文发起时间       说明：是否必填M 长度：6
		//收单行号变更
		String rcvMbrcd = StringUtil.trimObject(map.get("/root/MsgHeader/RcvBankId"));
		if(rcvMbrcd.length() !=4){
			//根据行号查找相应的orgId
			SqlSession mybatisSqlSession=(SqlSession) SpringUtil.getBean("mybatisSqlSession");
			ToOrgMapper toOrgMapper = mybatisSqlSession.getMapper(ToOrgMapper.class);
			ToOrg toOrg = new ToOrg();toOrg.setOrgBNo(rcvMbrcd);
			toOrg =toOrgMapper.queryByBNo(toOrg);
			if(toOrg == null){
				throw new BaseException(RespCd.NCPS5005,"数据库中无此数据");
			}
			rcvMbrcd = toOrg.getOrgId();
		}
		xmlReqDoc.setNodeContentTrim("transaction/header/msg/rcvMbrCd", rcvMbrcd);  //报文接收成员编号

		xmlReqDoc.setNodeContentTrim("transaction/header/msg/rcvAppCd", "CBS");  //报文接收应用编号
//		xmlReqDoc.setNodeContentTrim("transaction/header/msg/rcvAppCd", StringUtil.trimObject(map.get("/root/MsgHeader/RcvSysId")));  //报文接收应用编号
		xmlReqDoc.setNodeContentTrim("transaction/header/pnt/sndTm", time);  //请求发起方发送时间   说明：是否必填O 长度：6
		xmlReqDoc.setNodeContentTrim("transaction/header/pnt/sndDt",date);  //请求发起方发送日期   说明：是否必填O 长度：8
		xmlReqDoc.setNodeContentTrim("transaction/header/pnt/sndMbrCd", "0000"); //请求发起方成员编号
		xmlReqDoc.setNodeContentTrim("transaction/header/pnt/sndAppCd", "NNS"); //请求发起方应用编号
//		xmlReqDoc.setNodeContentTrim("transaction/header/pnt/sndAppCd", StringUtil.trimObject(map.get("/root/MsgHeader/SndSysId"))); //请求发起方应用编号
		xmlReqDoc.setNodeContentTrim("transaction/header/pnt/rcvMbrCd",rcvMbrcd); //接收方成员编号
		xmlReqDoc.setNodeContentTrim("transaction/header/pnt/rcvAppCd","CBS");  //接收方应用编号
//		xmlReqDoc.setNodeContentTrim("transaction/header/pnt/rcvAppCd",StringUtil.trimObject(map.get("/root/MsgHeader/RcvSysId")));  //接收方应用编号

	}

	/**
	 * CBS0003300报文
	 * @param map
	 * @return
	 * @throws DocumentException 
	 */
    public static  String buildXmlCBS3300(Map map)  {
		LOGGER.info("--------组装CBS0003300报文--------");
		try {    		
	    	XMLNodeUtil xmlReqDoc = new XMLNodeUtil(XMLNodeUtil.FROM_FILE,  SysDef.WORK_DIR + SystemParameter.SRC_PATH+SysDef.FILE_SP+"xml"
					+ SysDef.FILE_SP+"CBS"+SysDef.FILE_SP+"CBS_3300.xml");
			//报文头
			buildXmlRequestHead(xmlReqDoc,MsgCdOrTpEnum.CBS_3300.getCode(),map);
			//报文体
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/chnlSeqNb", StringUtil.trimObject(map.get("/root/MsgHeader/TrxId")));//渠道流水号 M
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/cardAcctFlg", StringUtil.trimObject(map.get("/root/MsgBody/PyerInf/PyerAcctTp")));//卡账号标志 M
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/payCardAcctNb", StringUtil.trimObject(map.get("/root/MsgBody/PyerInf/PyerAcctNo")));//转出卡号/账号 M
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/payCurTyp", StringUtil.trimObject(map.get("/root/MsgBody/TrxInf/TrxCurTp")));//转出币种   M
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/payCashFlg", StringUtil.trimObject(map.get("/root/MsgBody/TrxInf/TrxCashTp")));//转出钞汇标志  O
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/payCustNm", StringUtil.trimObject(map.get("/root/MsgBody/PyerInf/PyerAcctNm")));//转出客户名称  M
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/payBrchID", StringUtil.trimObject(map.get("/root/MsgBody/PyerInf/PyerBrnchId")));//转出账户开户网点号     O
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/payBrchNm", StringUtil.trimObject(map.get("/root/MsgBody/PyerInf/PyerBrnchNm")));//转出账户开户网点名称   O
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/chkPwdFlg", StringUtil.trimObject(map.get("/root/MsgBody/PyerInf/PyerAcctPwdFlg")));//是否校验密码  M
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/pwdTyp", StringUtil.trimObject(map.get("/root/MsgBody/PyerInf/PyerAcctPwdTp")));//密码类型   当校验转出卡/账号密码时必输
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/pwd", StringUtil.trimObject(map.get("/root/MsgBody/PyerInf/PyerAcctPwd")));//密码       当校验转出卡/账号密码时必输
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/transferMark",  StringUtil.trimObject(map.get("/root/MsgBody/TrxInf/TransferMark")));//转账标志  o
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/transferChnl",  StringUtil.trimObject(map.get("/root/MsgBody/TrxInf/TransferChnl")));//转账渠道   O
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/fastFlg", StringUtil.trimObject(map.get("/root/MsgBody/TrxInf/TrxFastFlg")));//加急标志   O
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/manualFlg", StringUtil.trimObject(map.get("/root/MsgBody/TrxInf/TrxRmanualFlg")));//落地标志   O
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/rcvAcct", StringUtil.trimObject(map.get("/root/MsgBody/PyeeInf/PyeeAcctNo")));//转入账号   M
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/rcvCustNm", StringUtil.trimObject(map.get("/root/MsgBody/PyeeInf/PyeeAcctNm")));//转入户名   M
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/rcvAcctSvcr", StringUtil.trimObject(map.get("/root/MsgBody/PyeeInf/PyeeBrnchId")));//转入行行号 M
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/rcvAcctSvcrNm", StringUtil.trimObject(map.get("/root/MsgBody/PyeeInf/PyeeBrnchNm")));//转入行行名 M
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/transAmt", StringUtil.trimObject(map.get("/root/MsgBody/TrxInf/TrxAmt")));//转出金额   M
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/feeFlg", StringUtil.trimObject(map.get("/root/MsgBody/TrxInf/")));//手续费标志 O
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/fee", StringUtil.trimObject(map.get("/root/MsgBody/TrxInf/TrxFeeAmt")));//手续费金额 当收手续费时必输
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/use", StringUtil.trimObject(map.get("/root/MsgBody/TrxInf/TrxPurPose")));//用途 O
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/memo", StringUtil.trimObject(map.get("/root/MsgBody/TrxInf/TrxRemark")));//备注 O
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/remarkCd", StringUtil.trimObject(map.get("/root/MsgBody/TrxInf/TrxUstrdCd")));//摘要代码   O
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/remark", StringUtil.trimObject(map.get("/root/MsgBody/TrxInf/TrxUstrd")));//摘要       O
			LOGGER.info("CBS0003300报文[{}]",xmlReqDoc.dumpToBuff());
			return xmlReqDoc.dumpToBuff();
		}catch (BaseException e) {
			throw e;
		} catch (Exception e) {
    		LOGGER.error("CBS0003300报文组装失败",e);
			throw new BaseException(RespCd.NCPS2402,e,"CBS0003300报文组装失败");
		}

    }

	/**
	 * C积分支付报文CBS10830报文
	 * @param map
	 * @return String
	 * @throws DocumentException
	 */
	public static String buildCBS10830Xml(Map<String, String> map){
		LOGGER.info("---------积分支付报文CBS10830--------");
		try{
			XMLNodeUtil xmlReqDoc = new XMLNodeUtil(XMLNodeUtil.FROM_FILE, SysDef.WORK_DIR + SystemParameter.SRC_PATH +SysDef.FILE_SP+"xml" +SysDef.FILE_SP+"CBS"+ SysDef.FILE_SP+"CBS_10830.xml");
			//报文头
			buildXmlRequestHead(xmlReqDoc,MsgCdOrTpEnum.CBS_10830.getCode(),map);
			//报文体
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/cardNb",         StringUtil.trimObject(map.get("/root/MsgBody/PyerInf/PyerAcctNo")));     //卡号                说明：M	借记卡卡号/贷记卡卡号
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/cardAcctFlg",    StringUtil.trimObject(map.get("/root/MsgBody/PyerInf/PyerAcctTp")));     //卡账号标志          说明：M	参见附录A.12卡账号标志
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/chkPwdFlg",      StringUtil.trimObject(map.get("/root/MsgBody/PyerInf/PyerAcctPwdFlg")));     //是否校验密码        说明：M	0－不校验；1－校验
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/pwdTyp",         StringUtil.trimObject(map.get("/root/MsgBody/PyerInf/PyerAcctPwdTp")));     //密码类型            说明：O	当校验转出卡/账号密码时必输
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/pwd",            StringUtil.trimObject(map.get("/root/MsgBody/PyerInf/PyerAcctPwd")));     //密码                说明：O	当校验转出卡/账号密码时必输
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/transferMark",   StringUtil.trimObject(map.get("/root/MsgBody/TrxInf/TransferMark")));     //转账标志            说明：O	1-转入2-转出3-不填有后台系统判断
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/transferChnl",   StringUtil.trimObject(map.get("/root/MsgBody/TrxInf/TransferChnl")));     //转账渠道            说明：O	1－B2B,2－B2C,3－PC快捷支付,4－移动快捷支付,5- 订单支付,6- 扫码支付
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/chnlSeqNb",      StringUtil.trimObject(map.get("/root/MsgBody/TrxInf/TrxId")));     //交易流水号          说明：M
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/transBonus",     StringUtil.trimObject(map.get("/root/MsgBody/PyerInf/TransBonus")));     //积分数量            说明：M	积分数量
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/instalAmt",      StringUtil.trimObject(map.get("/root/MsgBody/PyerInf/InstalAmt")));     //积分折算货币        说明：M
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/exchPercent",    StringUtil.trimObject(map.get("/root/MsgBody/PyerInf/ExchPercent")));     //积分兑换比率        说明：M	例如10000:1
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/branchId",       StringUtil.trimObject(map.get("/root/MsgBody/MrchntInf/MrchntNo")));     //商户编号            说明：O
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/branchName",     StringUtil.trimObject(map.get("/root/MsgBody/MrchntInf/MrchntNm")));     //商户名称            说明：O
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/merchantId",     StringUtil.trimObject(map.get("/root/MsgBody/GoodsInf/GoodsNo")));     //商品编号            说明：O
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/goodsName",      StringUtil.trimObject(map.get("/root/MsgBody/GoodsInf/GoodsNm")));     //商品名称            说明：O	若存在多个商品名称，需以“|”作为分隔拼接字符串发送
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/goodsType",      StringUtil.trimObject(map.get("/root/MsgBody/GoodsInf/GoodsTp")));     //商品类别            说明：O	若存在多个商品类别，需以“|”作为分隔拼接字符串发送
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/transDate",      StringUtil.trimObject(map.get("/root/MsgBody/TrxInf/TrxDt")));     //交易日期            说明：M
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/feeFlag",        StringUtil.trimObject(map.get("/root/MsgBody/TrxInf/TrxFeeFlg")));     //手续费标识          说明：O	0－不收手续费；1－收手续费
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/transFee",       StringUtil.trimObject(map.get("/root/MsgBody/TrxInf/TrxFeeAmt")));     //手续费              说明：O
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/use",            StringUtil.trimObject(map.get("/root/MsgBody/TrxInf/TrxPurPose")));     //用途                说明：O
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/remarkCd",       StringUtil.trimObject(map.get("/root/MsgBody/TrxInf/TrxUstrdCd")));     //摘要代码            说明：O
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/remark",         StringUtil.trimObject(map.get("/root/MsgBody/TrxInf/TrxUstrd")));     //摘要                说明：O
			return xmlReqDoc.toString();
		} catch (Exception e) {
			LOGGER.error("积分支付CBS10830报文失败",e);
			throw new BaseException(RespCd.NCPS2402,e,"积分支付CBS10830报文失败");
		}

	}


	/**
	 * 支付结果流水查证申请报文
	 * @param map
	 * @return String
	 * @throws DocumentException
	 */
	public static String buildCBS10860Xml(Map<String, String> map) {
		LOGGER.info("---------支付结果流水查证申请报文CBS10860--------");
		try {
			XMLNodeUtil xmlReqDoc = new XMLNodeUtil(XMLNodeUtil.FROM_FILE, SysDef.WORK_DIR + SystemParameter.SRC_PATH + SysDef.FILE_SP + "xml" + SysDef.FILE_SP + "CBS" + SysDef.FILE_SP + "CBS_10860.xml");
			//报文头
			buildXmlRequestHead(xmlReqDoc, MsgCdOrTpEnum.CBS_10860.getCode(), map);
			//报文体
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/chnlSeqNb", map.get("/root/MsgBody/TrxInf/TrxId"));     //交易流水号M	说明：发往核心的流水号
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/systemId", "");     //目标系统标识M	说明：01-借记卡系统；02-贷记卡系统；03-积分系统
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/commitDt", map.get("/root/MsgBody/TrxInf/TrxDt"));     //提交日期M	    说明：例如 20171204

			return xmlReqDoc.toString();
		} catch (Exception e) {
			LOGGER.error("支付结果流水查证申请报文CBS10830失败", e);
			throw new BaseException(RespCd.NCPS2402, e, "支付结果流水查证申请报文CBS10830失败");
		}
	}

	/**
	 * 积分退货申请报文
	 * @param map
	 * @return String
	 * @throws DocumentException
	 */
	public static String buildCBS10840Xml(Map<String, String> map) {
		LOGGER.info("---------积分退货申请报文CBS10840--------");
		try {
			XMLNodeUtil xmlReqDoc = new XMLNodeUtil(XMLNodeUtil.FROM_FILE, SysDef.WORK_DIR + SystemParameter.SRC_PATH + SysDef.FILE_SP + "xml" + SysDef.FILE_SP + "CBS" + SysDef.FILE_SP + "CBS_10840.xml");
			//报文头
			buildXmlRequestHead(xmlReqDoc, MsgCdOrTpEnum.CBS_10840.getCode(), map);
			//报文体
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/chnlSeqNb ",        StringUtil.trimObject(map.get("/root/MsgBody/BizInf/TrxId")));     //网关支付系统生成退货交易流水号
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/oldChnlSeqNb",      StringUtil.trimObject(map.get("/root/MsgBody/BizInf/OriTrxId")));     // 已成功的原交易流水号
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/oldTransBonusAmt",  StringUtil.trimObject(map.get("/root/MsgBody/BizInf/OriBonusAmt")));
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/oldInstalAmt",      StringUtil.trimObject(map.get("/root/MsgBody/BizInf/OriTrxAmt")));
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/transBonusAmt",     StringUtil.trimObject(map.get("/root/MsgBody/BizInf/TrxBonusAmt")));
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/instalAmt",         StringUtil.trimObject(map.get("/root/MsgBody/BizInf/TrxAmt")));
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/transDate",         StringUtil.trimObject(map.get("/root/MsgBody/BizInf/TrxDt")));     //积分退货请求发送日期20171204
			xmlReqDoc.setNodeContentTrim("/transaction/body/request/transDesc",         StringUtil.trimObject(map.get("/root/MsgBody/BizInf/Remark")));     //交易流水号M	说明：发往核心的流水号
			return xmlReqDoc.toString();
		} catch (Exception e) {
			LOGGER.error("积分退货申请报文CBS10840失败", e);
			throw new BaseException(RespCd.NCPS2402, e, "积分退货申请报文CBS10840失败");
		}
	}


}
